dbus 工具
·
Table of Contents
学习项目
- zbus https://github.com/z-galaxy/zbus
- pydbus https://github.com/LEW21/pydbus
- python-dbus-next https://github.com/altdesktop/python-dbus-next
- pystemd https://github.com/systemd/pystemd
- bluez-test https://github.com/bluez/bluez/tree/master/test
- Ulauncher https://github.com/Ulauncher/Ulauncher
- busctl https://github.com/systemd/systemd/tree/main/src/busctl
- xdg-desktop-portal https://github.com/flatpak/xdg-desktop-portal
GitHub 实战项目(可直接运行/贡献)
| system76-scheduler | 调度器 GUI,用 DBus 控制 systemd/CPU | Python + pydbus | org.freedesktop.systemd1, logind |
|---|---|---|---|
| gnome-shell-screenshot | 类 Flameshot 工具 | JS + DBus | portal.Screenshot, portal.Clipboard |
| blueman | 蓝牙管理器(Python) | pydbus + GTK | org.bluez, obex 协议 |
| udisks2-wrapper | 磁盘挂载示例 | pydbus | org.freedesktop.UDisks2 |
DBus 工具类
| 项目 | 描述 |
|---|---|
| d-spy | GTK DBus Inspector(看接口/发请求) ✅ 强烈推荐安装 |
| dbus-next | 纯 Python async DBus 实现(兼容性好) |
| xdg-desktop-portal | 官方测试用例(含 Python)→ 学 a{sv} 参数构造 |
| portal-test | 专测 portal 接口的工具 |
快速上手:5 个常用服务实战代码
- 依赖:pip install pydbus(初学)或 pip install zbus(进阶)
- 1️⃣ 发送桌面通知(org.freedesktop.Notifications)
# notify.py
from pydbus import SessionBus
bus = SessionBus()
notif = bus.get('.Notifications')
# 发送通知
notif.Notify(
"MyApp", # app_name
0, # replaces_id
"", # app_icon
"标题", # summary
"消息内容", # body
[], # actions
{"urgency": 1}, # hints (a{sv})
5000 # timeout ms
)
✅ 运行:python3 notify.py → 右上角弹出通知
- 2️⃣ 控制蓝牙开关(org.bluez)
# bluetooth.py
from pydbus import SystemBus
bus = SystemBus()
# 获取默认适配器(如 hci0)
adapter = bus.get('org.bluez', '/org/bluez/hci0')
print("Powered:", adapter.Powered)
adapter.Powered = False # 关闭蓝牙
# adapter.Powered = True # 开启
⚠️ 需权限:sudo usermod -aG bluetooth $USER + 重登
- 3️⃣ 查询电池状态(org.freedesktop.UPower)
# battery.py
from pydbus import SystemBus
bus = SystemBus()
upower = bus.get('org.freedesktop.UPower', '/org/freedesktop/UPower')
for dev_path in upower.EnumerateDevices():
dev = bus.get('org.freedesktop.UPower', dev_path)
if dev.Type == 2: # 2 = Battery
print(f"电量: {dev.Percentage:.1f}% | 状态: {dev.State}")
- 4️⃣ 调用截图 portal(解决你的 Flameshot 问题!)
# portal_screenshot.py
from pydbus import SessionBus
import time
bus = SessionBus()
portal = bus.get('org.freedesktop.portal.Desktop',
'/org/freedesktop/portal/desktop')
# 创建 Request 对象
request = bus.get('org.freedesktop.portal.Desktop',
portal.Request.CreateRequest('', '')[0])
# 触发截图(interactive 模式)
opts = {
'modal': True,
'interactive': True
}
portal.Screenshot(request, opts)
# 监听 Response(简化版)
def on_response(response, results):
if response == 0: # 0 = success
print("截图保存路径:", results.get('uri'))
else:
print("用户取消或失败")
request.onResponse = on_response
time.sleep(10) # 等待用户操作
✅ 运行后弹出 GNOME 截图界面 → 标注后保存路径打印到终端
- 5️⃣ 重启 systemd 用户服务(org.freedesktop.systemd1)
# restart_service.py
from pydbus import SessionBus
bus = SessionBus()
systemd = bus.get('.systemd1')
# 重启 flameshot 服务(若配置了 autostart)
systemd.RestartUnit('flameshot.service', 'replace')
print("Flameshot 服务已重启")
调试技巧(结合你之前的环境)
- 快速定位 portal 问题:
# 1. 监控 portal 通信
busctl --session monitor --match="interface='org.freedesktop.portal.*'"
# 2. 检查 polkit 规则
pkaction --verbose --action-id org.freedesktop.portal.desktop.screenshot
# 3. 手动测试权限
gdbus call --session \
--dest org.freedesktop.portal.Desktop \
--object-path /org/freedesktop/portal/desktop \